package com.rem.chat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rem.chat.common.errcode.ServiceErrorCodeConstants;
import com.rem.chat.common.exception.ServiceException;
import com.rem.chat.common.utils.BeanTransUtil;
import com.rem.chat.common.utils.RedisComponent;
import com.rem.chat.common.utils.StringUtil;
import com.rem.chat.mapper.*;
import com.rem.chat.pojo.dataobject.*;
import com.rem.chat.pojo.request.UserStatusModifyRequest;
import com.rem.chat.pojo.request.PageRequest;
import com.rem.chat.pojo.response.LoadAllGroupResponse;
import com.rem.chat.pojo.response.LoadAllUserResponse;
import com.rem.chat.service.AdminService;
import com.rem.chat.service.dto.MessageSendDTO;
import com.rem.chat.service.enums.*;
import com.rem.chat.websocket.MessageHandler;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author: Themberfue
 * @date: 2025/6/9 17:08
 * @description:
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Resource
    UserInfoMapper userInfoMapper;

    @Resource
    GroupInfoMapper groupInfoMapper;

    @Resource
    UserContactMapper userContactMapper;

    @Resource
    ChatSessionMapper chatSessionMapper;

    @Resource
    ChatMessageMapper chatMessageMapper;

    @Resource
    RedisComponent redisComponent;

    @Resource
    MessageHandler messageHandler;

    @Override
    public LoadAllUserResponse loadAllUser(PageRequest param) {
        // Step 1. 校验参数
        if (null == param) {
            param = new PageRequest();
        }

        // Step 2. 查询所有的用户数量
        Long total = userInfoMapper.selectCount(new QueryWrapper<>());

        // Step 3. 进行分页查询
        Page<UserInfoDO> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper<UserInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .orderByDesc(UserInfoDO::getCreateTime);

        List<LoadAllUserResponse.UserInfo> userInfoResponseList = userInfoMapper.selectList(page, queryWrapper)
                .stream()
                .map(BeanTransUtil::transToUserInfo)
                .toList();

        return new LoadAllUserResponse(total, userInfoResponseList);
    }

    @Override
    public Boolean modifyUserStatus(UserStatusModifyRequest request) {
        // Step 1-2: 校验用户状态
        UserInfoDO userInfoDO = validateUserStatus(request);

        // Step 3. 更新用户状态
        userInfoDO.setStatus(request.getStatus());
        userInfoMapper.updateById(userInfoDO);

        return true;
    }

    @Override
    public Boolean forceOffLine(String userId) {
        // Step 强制下线
        MessageSendDTO<Object> messageSendDTO = MessageSendDTO.builder()
                .contactId(userId)
                .messageType(MessageTypeEnum.FORCE_OFF_LINE.getType())
                .contactType(UserContactTypeEnum.USER.getType())
                .build();
        messageHandler.sendMessage(messageSendDTO);
        return null;
    }

    @Override
    public LoadAllGroupResponse loadAllGroup(PageRequest param) {
        // Step 1. 校验参数
        if (null == param) {
            param = new PageRequest();
        }

        // Step 2. 查询所有群组数量
        Long total = groupInfoMapper.selectCount(new QueryWrapper<>());

        // Step 3. 进行分页查询
        Page<GroupInfoDO> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper<GroupInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .orderByDesc(GroupInfoDO::getCreateTime);
        List<LoadAllGroupResponse.GroupInfo> groupInfoResponseList = groupInfoMapper.selectAllGroupInfo(page)
                .getRecords()
                .stream()
                .map(BeanTransUtil::transToGroupInfo)
                .toList();

        return new LoadAllGroupResponse(total, groupInfoResponseList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean dissolutionGroup(String groupId, String userId) {
        // Step 1. 查询群组信息是否存在
        GroupInfoDO groupInfoDO = validateGroup(groupId, userId);

        // Step 2. 更新群组和群成员状态
        updateGroupAndMemberStatus(groupInfoDO, groupId);

        // Step 3. 移除相关群员的联系人缓存
        QueryWrapper<UserContactDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(UserContactDO::getContactId, groupId);
        List<UserContactDO> contactList = userContactMapper.selectList(queryWrapper);
        for (UserContactDO contact: contactList) {
            redisComponent.removeUserContact(contact.getUserId(), contact.getContactId());
        }

        // Step: 4-6 更新会话信息 记录群消息 发送解散通知消息
        String sessionId = StringUtil.getSessionId(new String[]{groupId});
        ChatSessionDO chatSessionDO = ChatSessionDO.builder()
                .sessionId(sessionId)
                .lastMessage(MessageTypeEnum.DISSOLUTION_GROUP.getInitMessage())
                .lastReceiveTime(System.currentTimeMillis())
                .build();
        chatSessionMapper.updateById(chatSessionDO);

        ChatMessageDO chatMessageDO = ChatMessageDO.builder()
                .sessionId(sessionId)
                .contactType(UserContactTypeEnum.GROUP.getType())
                .status(MessageStatusEnum.SENT.getStatus())
                .messageType(MessageTypeEnum.DISSOLUTION_GROUP.getType())
                .contactId(groupId)
                .messageContent(MessageTypeEnum.DISSOLUTION_GROUP.getInitMessage())
                .build();
        chatMessageMapper.insert(chatMessageDO);

        MessageSendDTO<Object> messageSendDTO = BeanUtil.copyProperties(chatMessageDO, MessageSendDTO.class);
        messageHandler.sendMessage(messageSendDTO);

        return true;
    }

    private UserInfoDO validateUserStatus(UserStatusModifyRequest request) {
        // 校验用户状态
        UserStatusEnum statusEnum = UserStatusEnum.getByStatus(request.getStatus());
        if (null == statusEnum) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_STATUS_WRONG);
        }

        // 校验用户是否存在
        UserInfoDO userInfoDO = userInfoMapper.selectById(request.getUserId());
        if (null == userInfoDO) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_IS_NOT_EXISTS);
        }
        return userInfoDO;
    }

    private GroupInfoDO validateGroup(String groupId, String userId) {
        // Step 1. 查询群组信息是否存在
        GroupInfoDO groupInfoDO = groupInfoMapper.selectById(groupId);
        if (null == groupInfoDO) {
            throw new ServiceException(ServiceErrorCodeConstants.GROUP_IS_NOT_EXISTS);
        }

        if (!groupInfoDO.getGroupOwnerId().equals(userId)) {
            throw new ServiceException(ServiceErrorCodeConstants.NOT_USER_OPERATE);
        }
        return groupInfoDO;
    }

    private void updateGroupAndMemberStatus(GroupInfoDO groupInfoDO, String groupId) {
        // Step 更新群组状态
        groupInfoDO.setStatus(GroupStatusEnum.DISSOLUTION.getStatus());
        groupInfoMapper.updateById(groupInfoDO);

        //  Step 更新群成员与该群的状态
        UpdateWrapper<UserContactDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .eq(UserContactDO::getContactId, groupId)
                .set(UserContactDO::getStatus, UserContactStatusEnum.DEL.getStatus());
        userContactMapper.update(updateWrapper);
    }
}
